import React, { Component } from "react";
import { Row, Col, Input, Select, Button, Modal } from "antd";
import PropTypes from "prop-types";
import ReactJson from "react-json-view";
import { connect } from "react-redux";
import { FormattedMessage } from "react-intl";
import { testapi } from "@service/form";
import messages from "@i18n/messages";
import { apiAction } from "../redux/actions";
import ACTION_TYPE from "../redux/constant/action-types";
import { Param } from "./model";
import { RESPONSE_TYPE } from "./constant";
import "./Detail.less";

function mapStateToProps(state) {
  return {
    updateApiLoading: state.loading[ACTION_TYPE.REQUEST_UPDATE_API_PROVIDER],
  };
}

function mapDispatchToProps(dispatch) {
  return {
    update: (id, api) => dispatch(apiAction.requestUpdate(id, api)),
  };
}

@connect(
  mapStateToProps,
  mapDispatchToProps
)
class Detail extends Component {
  static propTypes = {
    api: PropTypes.object.isRequired,
  };
  
  constructor(props) {
    super(props);
    this.state = {
      modalVisible: false,
      tempParam: Param.create(),
      api: props.api,
      lastApi: props.lastApi,
      json: {},
      keylist: [],
      key: [],
    };
  }

  componentDidMount(){
    this.props.onRef(this);
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.api !== prevState.lastApi) {
      return {
        api: nextProps.api,
        lastApi: nextProps.api,
        key: nextProps.api.keylist ? nextProps.api.keylist : [],
        keylist: nextProps.api.keys ? nextProps.api.keys : [],
      };
    }
    return null;
  }

  save = () => {
    const { api } = this.state;
    const { update } = this.props;
    update(api.id, api);
  };

  handleChange=(value, index) => {
    const { key } = this.state;
    key[index].dataIndex = value;
    this.setState({
      key,
    });
  }

  test = async () => {
    const { api } = this.state;
    const result = await testapi(api.url, api.method);
    const { data } = result;
    const newApi = api.set('keys', Object.keys(data[0]));
    this.setState({
      json: result,
      keylist: Object.keys(data[0]),
      api: newApi,
    });
  };

  add = () => {
    this.setState(state => {
      return { key: [ ...state.key, { dataIndex: "", title: "" } ] };
    });
  };

  onChange = (value, property) => {
    const { api } = this.state;
    const newApi = api.set(property, value);
    this.setState({
      api: newApi,
    });
  };

  savekey=() => {
    const { key } = this.state;
    this.onChange(key, 'keylist');
  }

  updateParameter = (param, index) => {
    const { api } = this.props;
    const params = api.params.set(index, param);
    this.onChange(params, "params");
  };

  addParameter = param => {
    const { api } = this.state;
    const params = api.params.push(param);
    this.onChange(params, "params");
  };

  onAddParameter = () => {
    this.setState({
      modalVisible: true,
      tempParam: Param.create(),
    });
  };

  renderAddParamModal = () => {
    const { modalVisible, tempParam } = this.state;
    const onOk = () => {
      this.addParameter(tempParam);
      this.setState({ modalVisible: false });
    };
    const onCancel = () => {
      this.setState({ modalVisible: false });
    };
    const onChange = (value, property) => {
      const param = tempParam.set(property, value);
      this.setState({
        tempParam: param,
      });
    };
    return (
      <Modal
        visible={modalVisible} onOk={onOk}
        onCancel={onCancel}
      >
        <Row>
          <Col span={4}>
            <span>name</span>
          </Col>
          <Col span={14}>
            <Input
              value={tempParam.name}
              onChange={event => onChange(event.target.value, "name")}
            />
          </Col>
        </Row>
        <Row style={{ marginTop: 10 }}>
          <Col span={4}>
            <span>defaultValue</span>
          </Col>
          <Col span={14}>
            <Input
              value={tempParam.defaultValue}
              onChange={event => onChange(event.target.value, "defaultValue")}
            />
          </Col>
        </Row>
        <Row style={{ marginTop: 10 }}>
          <Col span={4}>
            <span>type</span>
          </Col>
          <Col span={14}>
            <Select
              value={tempParam.type}
              onChange={value => onChange(value, "type")}
              style={{ width: "100%" }}
            >
              <Select.Option value="string">string</Select.Option>
              <Select.Option value="number">number</Select.Option>
            </Select>
          </Col>
        </Row>
      </Modal>
    );
  };

  renderParam = (param, index) => {
    const onChange = (value, property) => {
      const newParam = param.set(property, value);
      this.updateParameter(newParam, index);
    };
    return (
      <Row className="row" key={index}>
        <Col span={2}>name</Col>
        <Col span={4}>
          <Input
            value={param.name}
            onChange={event => onChange(event.target.value, "name")}
          />
        </Col>
        <Col span={2} offset={1}>
          type
        </Col>
        <Col span={4}>
          <Select
            onChange={value => onChange(value, "type")}
            value={param.type}
            style={{ width: "100%" }}
          >
            <Select.Option value="string">string</Select.Option>
            <Select.Option value="number">number</Select.Option>
          </Select>
        </Col>
        <Col span={2} offset={1}>
          default
        </Col>
        <Col span={4}>
          <Input
            value={param.defaultValue}
            onChange={event => onChange(event.target.value, "defaultValue")}
          />
        </Col>
      </Row>
    );
  };

  render() {
    // const { updateApiLoading } = this.props;
    const { api, json, keylist, key } = this.state;
    const hasParams = api.params.size > 0;
    const httpMethods = [ "GET", "POST", "DELETE", "HEAD" ];
    return (
      <div className="api-privder-detail">
        {/* <Row className="row">
          <Button
            loading={updateApiLoading}
            onClick={this.save}
            icon="save"
            type="primary"
          >
            Save
          </Button>
        </Row> */}
        <Row className="row">
          <Col span={4}>
            <FormattedMessage {...messages.apiName} />
          </Col>
          <Col span={12}>
            <Input
              onChange={event => this.onChange(event.target.value, "name")}
              value={api.name}
            />
          </Col>
        </Row>
        <Row className="row">
          <Col span={4}>
            <FormattedMessage {...messages.apiUrl} />
          </Col>
          <Col span={12}>
            <Input
              onChange={event => this.onChange(event.target.value, "url")}
              value={api.url}
            />
          </Col>
        </Row>
        <Row className="row">
          <Col span={4}>
            <FormattedMessage {...messages.apiMethod} />
          </Col>
          <Col span={9}>
            <Select
              value={api.method}
              onChange={value => this.onChange(value, "method")}
            >
              {httpMethods.map(method => (
                <Select.Option key={method} value={method}>
                  {method}
                </Select.Option>
              ))}
            </Select>
          </Col>
          <Col span={4}>
            <Button
              onClick={this.test} icon="cloud"
              type="primary"
            >
              测试接口
            </Button>
          </Col>
        </Row>
        <Row className="row">
          <Col span={4}>
            <FormattedMessage {...messages.apiResponseType} />
          </Col>
          <Col span={12}>
            <Select
              onChange={value => this.onChange(value, "responseType")}
              value={api.responseType}
            >
              <Select.Option key="object" value={RESPONSE_TYPE.OBJECT}>
                <FormattedMessage {...messages.apiResponseTypeObject} />
              </Select.Option>
              <Select.Option key="list" value={RESPONSE_TYPE.LIST}>
                <FormattedMessage {...messages.apiResponseTypeList} />
              </Select.Option>
            </Select>
          </Col>
        </Row>
        {hasParams && (
          <div>
            <div style={{ margin: "10px 0" }}>
              <FormattedMessage {...messages.apiParam} />
            </div>
            {api.params.map(this.renderParam)}
          </div>
        )}
        <Row className="row">
          <Col span={5}>
            <FormattedMessage {...messages.apiKey} />
          </Col>
          <Col span={7}>
            <Button
              onClick={this.add} icon="plus"
              type="primary"
            >
              添加key
            </Button>
          </Col>
          <Col span={4}>
            <Button
              onClick={this.savekey} icon="save"
              type="primary"
            >
              保存key
            </Button>
          </Col>
        </Row>
        {key.length > 0
          ? key.map((k, index) => (
            <div key={`${k}-${index}`} style={{ paddingTop: 10 }}>
              <Row key={`${k}-${index}`} className="row">
                <Col span={4}>
              字段选择
                </Col>
                <Col span={12}>
                  <Select
                    style={{ width: 120 }} defaultValue={key[index].dataIndex}
                    onChange={(v) => this.handleChange(v, index)}
                  >
                    {keylist.map((kl, _) => (
                      <Select.Option key={`${kl}-${_}`} value={kl}>{kl}</Select.Option>
                    ))}
                  </Select>
                </Col>
              </Row>
              <Row key={index} className="row">
                <Col span={4}>
                展示的字段名
                </Col>
                <Col span={12}><Input
                  onChange={({ target }) => {
                    this.setState(state => {                      
                      const { key } = state;
                      key[index].title = target.value;
                      return {
                        key,
                      };
                    });
                  }}
                  value={key[index].title}
                />
                </Col>
                <Col push={2} span={4}>
                  <Button onClick={() => {                                     
                    const { key } = this.state;
                    const temp = [...key];
                    temp.splice(index, 1);
                    this.setState({
                      key: temp,
                    });
                  }}
                  >
                  删除
                  </Button>
                </Col>
              </Row>
            </div>
          ))
          : null}

        <Row>
          <ReactJson
            style={{
              maxHeight: 500,
              overflow: 'scroll',
            }}
            enableClipboard={false}
            collapsed
            src={json}
            theme="apathy:inverted"
            name={false}
          />
        </Row>
        <Row className="row">
          <Button icon="plus" onClick={this.onAddParameter}>
            <FormattedMessage {...messages.apiAddParameter} />
          </Button>
        </Row>
        {this.renderAddParamModal()}
      </div>
    );
  }
}

export default Detail;
